package com.sduept.nwld.fault.outer.model.factory;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;

import com.sduept.bigdata.fault.entity.FaultRecord;
import com.sduept.bigdata.fault.entity.FaultReportMain;
import com.sduept.bigdata.fault.entity.FaultReportMainProtection;
import com.sduept.bigdata.fault.entity.FaultReportStationDetail;
import com.sduept.cim.model.core.Substation;
import com.sduept.cim.model.protection.ProtectionEquipment;
import com.sduept.cim.model.wires.DcLinesegment;
import com.sduept.nwld.fault.outer.model.FaultTripInfo;
import com.sduept.nwld.fault.outer.model.ProtectInfo;
import com.sduept.nwld.fault.outer.model.StationTripInfo;
import com.sduept.utils.DateUtil;


public class DclineOuterFaultModelFactory extends AbstractOuterFaultModelFactory{
	private static final String head_template="#{station}报#{devicename}保护动作情况：\n";
	private static final String dcline_body_template="#{protect}行波保护动作，测距#{distance}km，\n";
	private static final String dcline_footer_template="再启动情况：全压再启动#{reclose}，80%再启动，一次设备检查，现场天气#{weather}。";
	
	
	private static AbstractOuterFaultModelFactory factory = new DclineOuterFaultModelFactory();
	private DclineOuterFaultModelFactory(){}
	public static AbstractOuterFaultModelFactory getInstance(){
		return factory;
	}
	@Override
	public  FaultTripInfo getFaultTripInfo(FaultRecord record)throws Exception{
		List<FaultReportMain> mains  = superDao.findByCondition(FaultReportMain.class, "faultRecord.id=?", record.getId());
		if(mains.size()>0){
			return buildDcLineFaultTripInfo(record,mains.get(0));
		}
		return null;
	}
	/**
	 * @param record
	 * @param main
	 * @return
	 */
	private FaultTripInfo buildDcLineFaultTripInfo(FaultRecord record,FaultReportMain main){
		FaultTripInfo result = new FaultTripInfo();
		String deviceName = record.getEquipment();
		String deviceId = record.getEquipment_id();
		result.setId(record.getId());
		result.setStatus(record.getStatus());
		DcLinesegment line = cm.getDcLinesegmentById(deviceId);
		if(line!=null){
			result.setDeviceRdfId(line.getRdfId());
			result.setDeviceGid(line.getId());
		}
		result.setFaultDate(record.getFaultTime().getTime());
		result.setFaultPhase(record.getFaultPhase());
		result.setDeviceName(deviceName);
		Double startStationDistance = null;
		Double endStationDistance = null;
		for(FaultReportStationDetail sdetail: main.getFaultReportStationDetails()){
			StationTripInfo sti  = buildStationTripInfo(record.getFaultTime(),deviceName, deviceId,sdetail);
			if(StringUtils.isEmpty(sti.getRecolse())){
				result.setRecolse(sti.getRecolse());
			}
			//设置第一个站的行波测距
			if(startStationDistance==null && StringUtils.isNotEmpty(record.getStationId()) && record.getStationId().equals(sdetail.getStationId())){
				if(sdetail.getManualFaultRangingFirst()!=null){
					startStationDistance = sdetail.getManualFaultRangingFirst();
				}else if(sdetail.getManualFaultRangingSecond()!=null){
					startStationDistance = sdetail.getManualFaultRangingSecond();
				}else if(sdetail.getManualFaultRangingFirst()!=null){
					startStationDistance = sdetail.getManualFaultRangingThird();
				}else if(sdetail.getFaultRangingFirst()!=null){
					startStationDistance = sdetail.getFaultRangingFirst();
				}else if(sdetail.getFaultRangingSecond()!=null){
					startStationDistance = sdetail.getFaultRangingSecond();
				}else if(sdetail.getFaultRangingThird()!=null){
					startStationDistance = sdetail.getFaultRangingThird();
				}
			}//设置第二个站的行波测距
			else if(endStationDistance==null && StringUtils.isNotEmpty(record.getStationId2()) && record.getStationId2().equals(sdetail.getStationId())){
				if(sdetail.getManualFaultRangingFirst()!=null){
					endStationDistance = sdetail.getManualFaultRangingFirst();
				}else if(sdetail.getManualFaultRangingSecond()!=null){
					endStationDistance = sdetail.getManualFaultRangingSecond();
				}else if(sdetail.getManualFaultRangingFirst()!=null){
					endStationDistance = sdetail.getManualFaultRangingThird();
				}else if(sdetail.getFaultRangingFirst()!=null){
					endStationDistance = sdetail.getFaultRangingFirst();
				}else if(sdetail.getFaultRangingSecond()!=null){
					endStationDistance = sdetail.getFaultRangingSecond();
				}else if(sdetail.getFaultRangingThird()!=null){
					endStationDistance = sdetail.getFaultRangingThird();
				}
			}
			result.getStationTripInfos().add(sti);
		}
		//设置全压再启动是否成功
		StringBuilder sb = new StringBuilder(DateUtil.getStringDate(new Date(result.getFaultDate()), DateUtil.pattern_ymdhm)+"，"+deviceName);
		if(StringUtils.isNotEmpty(result.getFaultPhase())){
			sb.append("，"+result.getFaultPhase());
		}
		sb.append("跳闸");
		if(StringUtils.isNotEmpty(result.getRecolse())){
			sb.append("，全压再启动"+result.getRecolse());
		}
		result.setTripName(sb.toString());
		
		// 设置故障分析信息
		StringBuilder faultAnlysis =  new StringBuilder();
		String iceAnlysisInfo  = wdm.getNewFaultIceInfo(record);
		if(StringUtils.isNotEmpty(iceAnlysisInfo)){
			faultAnlysis.append(iceAnlysisInfo+"\n");
		}
		String thunderAnlysisInfo  = wdm.getNewFaultThunderInfo(record);
		if(StringUtils.isNotEmpty(thunderAnlysisInfo)){
			faultAnlysis.append(thunderAnlysisInfo);
		}
		if(StringUtils.isNotEmpty(faultAnlysis.toString())){
			result.setFaultAnlysis(faultAnlysis.toString());
		}
		//设置天气
		Integer tower = null;
		if(startStationDistance!=null){
			tower = fam.getTowerNo(startStationDistance, null, deviceId);
		}else if(endStationDistance!=null){
			tower = fam.getTowerNo(null, endStationDistance, deviceId);
		}
		if(tower!=null){
			String weather = wm.findWeatherByTower(deviceId, tower, record.getFaultTime());
			for(StationTripInfo st:result.getStationTripInfos()){
				st.setWeather(weather);
			}
		}
		return result;
	}
	/**
	 * 构建变电站跳闸信息
	 * @param smodel
	 * @param pmodel
	 * @return
	 */
	private StationTripInfo buildStationTripInfo(Date faultTime,String deviceName,String deviceId,FaultReportStationDetail sdetail){
		StationTripInfo result = new StationTripInfo();
		if(StringUtils.isNotEmpty(sdetail.getStationId())){
			Substation station =  cm.getStationById(sdetail.getStationId());
			if(station!=null){
				result.setStationRdfId(station.getRdfId());
				result.setStationGid(station.getId());
			}
		}
		result.setStationName(sdetail.getStationName());
		if(sdetail.getManualFaultRangingFirst()!=null && sdetail.getManualFaultRangingFirst()>0){
			double df = getNeededPrecisionNumber(sdetail.getManualFaultRangingFirst()); 
			result.setTravellingWave(df);
		}else if(sdetail.getManualFaultRangingSecond()!=null && sdetail.getManualFaultRangingSecond()>0){
			double df = getNeededPrecisionNumber(sdetail.getManualFaultRangingSecond()); 
			result.setTravellingWave(df);
		}else if(sdetail.getManualFaultRangingThird()!=null && sdetail.getManualFaultRangingThird()>0){
			double df = getNeededPrecisionNumber(sdetail.getManualFaultRangingThird()); 
			result.setTravellingWave(df);
		}
		if("是".equals(sdetail.getReclosingSuccess())){
			result.setRecolse("成功");
		}else if("否".equals(sdetail.getReclosingSuccess())){
			result.setRecolse("失败");
		}
		List<ProtectionEquipment> pelist = cm.listMainEquipmentsByStationIdAndprotectedId(sdetail.getStationId(), deviceId);
		//构建厂站保护信息
		List<ProtectInfo> list = buildProtectInfo(pelist,sdetail.getFaultReportMainProtectionActions(), deviceName,faultTime,sdetail.getStationName());
		String str = head_template.replace("#{station}", sdetail.getStationName()).replace("#{devicename}", deviceName);
		StringBuilder sb = new StringBuilder(str);
		for(ProtectInfo pi:list){
			if("主一保护".equals(pi.getProtectName())){
				if(sdetail.getManualFaultRangingFirst()!=null && sdetail.getManualFaultRangingFirst()>0){
					double df = getNeededPrecisionNumber(sdetail.getManualFaultRangingFirst()); 
					pi.setDistance(df);
				}else if(sdetail.getFaultRangingFirst()!=null && sdetail.getFaultRangingFirst()>0){
					double df = getNeededPrecisionNumber(sdetail.getFaultRangingFirst()); 
					pi.setDistance(df);
				}
			}else if("主二保护".equals(pi.getProtectName())){
				if(sdetail.getManualFaultRangingSecond()!=null && sdetail.getManualFaultRangingSecond()>0){
					double df = getNeededPrecisionNumber(sdetail.getManualFaultRangingSecond()); 
					pi.setDistance(df);
				}else if(sdetail.getFaultRangingSecond()!=null && sdetail.getFaultRangingSecond()>0){
					double df = getNeededPrecisionNumber(sdetail.getFaultRangingSecond()); 
					pi.setDistance(df);
				}
			}else if("主三保护".equals(pi.getProtectName())){
				if(sdetail.getManualFaultRangingThird()!=null && sdetail.getManualFaultRangingThird()>0){
					double df = getNeededPrecisionNumber(sdetail.getManualFaultRangingThird()); 
					pi.setDistance(df);
				}else if(sdetail.getFaultRangingThird()!=null && sdetail.getFaultRangingThird()>0){
					double df = getNeededPrecisionNumber(sdetail.getFaultRangingThird()); 
					pi.setDistance(df);
				}
			}
			str = dcline_body_template.replace("#{protect}", pi.getProtectName());
			if(pi.getDistance()!=null && pi.getDistance()>0){
				str = str.replace("#{distance}", pi.getDistance()+"");
			}
			sb.append(str);
		}
		str =dcline_footer_template;
		if(result.getRecolse()!=null){
			str = str.replace("#{reclose}", result.getRecolse());
		}
		sb.append(str);
		String content = sb.toString().replaceAll("#\\{[a-z]+\\}", " ");
		result.setContent(content);
		result.getProtectInfos().addAll(list);
		return result;
	}
	/**
	 * 构造保护动作信息
	 * @param lineId
	 * @param model
	 * @return
	 */
	private List<ProtectInfo> buildProtectInfo(List<ProtectionEquipment> pelist,Collection<FaultReportMainProtection> mains,String deviceName,Date faultTime,String stationName){
		List<ProtectInfo> result = new ArrayList<ProtectInfo>();
		List<ProtectInfo> pilist = getSFProtectReport(faultTime, deviceName, stationName);
		//构造本次保护动作模型
		for(ProtectionEquipment pe:pelist){
			ProtectInfo info = new ProtectInfo();
			info.setProtectName(pe.getType());
			for(ProtectInfo pi:pilist){
				if(pe.getName().equals(pi.getProtectName())){
					info.setComponet(pi.getComponet());
					info.setDistance(pi.getDistance());
					break;
				}
			}
			for(FaultReportMainProtection main:mains){
				if(!"trip".equals(main.getActionType())){
					continue;
				}
				if(pe.getId().equals(main.getProtectionId())){
					if(StringUtils.isEmpty(info.getPhase())){
						info.setPhase(main.getPhase());
					}else{
						info.setPhase(info.getPhase()+main.getPhase());
					}
				}
			}
			if(StringUtils.isNotEmpty(info.getPhase())){
				char[] str=info.getPhase().toCharArray();
				Arrays.sort(str);
				String phase = new String(str);
				info.setPhase(phase);
			}
			result.add(info);
		}
		return result;
	}
}
